package com.jcliprunner;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.gnome.gtk.ButtonsType;
import org.gnome.gtk.Clipboard;
import org.gnome.gtk.MessageDialog;
import org.gnome.gtk.MessageType;
import org.gnome.gtk.WindowPosition;

public class Util {
	private File mainFile;
	private File shFile;

	public Util(String language) {
		if (language.equals("python")) {
			mainFile = getTempCodeFile(".py");
			shFile = createShFile(new String[] { "python " + getCodePath(), });
		} else if (language.equals("java")) {
			if (Clipboard.getDefault().getText().indexOf("public class") < 0) {
				alert("Java Problem", "This file not seems a java file");
				return;
			}
			mainFile = createJavaFile(".java");
			String rawName = getRawFile().getName();
			String tmpFile = mainFile.getParent();
			String[] parameters = new String[] { "javac " + getCodePath(),
					"cd " + tmpFile, "java " + rawName };
			shFile = createShFile(parameters);
		} else if (language.equals("php")) {
			mainFile = getTempCodeFile(".php");
			shFile = createShFile(new String[] { "php " + getCodePath() });
		} else if (language.equals("cpp")) {
			mainFile = getTempCodeFile(".cpp");
			String rawFile = getRawFile().getAbsolutePath();
			String[] parameters = new String[] {
					"g++ " + getCodePath() + " -o " + rawFile, rawFile };
			shFile = createShFile(parameters);
		} else if (language.equals("ruby")) {
			mainFile = getTempCodeFile(".rb");
			shFile = createShFile(new String[] { "ruby " + getCodePath() });
		}

		runCode();

	}

	public static boolean isClipBoardReady() {
		if (Clipboard.getDefault().getText()!=null) {
			if (!Clipboard.getDefault().getText().trim().equals(""))
				return true;
		}
		return false;
	}

	// class name in java file
	public String getClassName() {
		String text = Clipboard.getDefault().getText();
		int i = text.indexOf("public class");
		text = text.substring(i + 13);
		i = text.indexOf(' ');
		return text.substring(0, i);
	}

	public File createJavaFile(String ext) {
		File file;
		try {
			File tmpFile = File.createTempFile("aaa", "bbb");
			File dir = tmpFile.getParentFile();
			tmpFile.delete();
			String className = getClassName();
			file = new File(dir, className + ext);
			FileWriter fw = new FileWriter(file);
			fw.write(Clipboard.getDefault().getText());
			fw.close();

			return file;
		} catch (IOException e) {
			alert("Source Code Problem", "Selected code isn't read");
		} catch (Exception e) {
			alert("Hmmm unexcepted!", e.getMessage());
		}
		return null;

	}

	public File getTempCodeFile(String ext) {
		// tcf: an extension like temp code file
		File file;
		try {
			file = File.createTempFile("tcf", ext);
			FileWriter fw = new FileWriter(file);
			fw.write(Clipboard.getDefault().getText());
			fw.close();
			return file;
		} catch (IOException e) {
			alert("Source Code Problem", "Selected code isn't read");
		}
		return null;
	}

	public String getCodePath() {
		return mainFile.getAbsolutePath();
	}

	public File getRawFile() {
		// to remove java and C codes
		String rawName = mainFile.getAbsolutePath();
		int lastIndex = rawName.lastIndexOf('.');
		int nIndex = (lastIndex == -1) ? rawName.length() : lastIndex;
		File rawFile = null;
		rawFile = new File(rawName.substring(0, nIndex));
		return rawFile;
	}

	public void deleteFiles() {

		if (getRawFile().exists())
			getRawFile().delete();
		File classFile = new File(getRawFile() + ".class");
		if (classFile.exists())
			classFile.delete();
		// __________________________________-

		mainFile.delete();
		shFile.delete();
	}

	public void alert(String title, String message) {
		MessageDialog dialog = new MessageDialog(null, true, MessageType.ERROR,
				ButtonsType.OK, message);
		dialog.setTitle(title);
		dialog.setPosition(WindowPosition.CENTER_ALWAYS);
		dialog.run();
		dialog.hide();
	}

	public File createShFile(String[] commands) {
		File tmp = null;
		try {
			tmp = File.createTempFile("shf", ".sh");
			FileWriter fw = new FileWriter(tmp);
			fw.append("#!/bin/sh \n");
			for (String command : commands) {
				fw.append(command + "\n");
			}
			fw.append("echo \"*** Program Exit Code: $? ***\" \n");
			fw.append("echo \"Press return key to exit\" \n");
			fw.append("char=\"\" \n");
			fw.append("read char \n");
			fw.close();
		} catch (IOException e) {
		}
		return tmp;

	}

	public String getShFilePath() {
		return shFile.getAbsolutePath();
	}

	public void runCode() {
		Thread th = new Thread() {
			@Override
			public void run() {
				try {
					Process p = Runtime.getRuntime().exec(
							"xterm -e sh " + getShFilePath());
					p.waitFor();
					deleteFiles();
				} catch (IOException e) {
					alert("Compile Problem", e.getMessage());
				} catch (InterruptedException e) {
				}
			}
		};
		th.start();
	}

}
